Micron Document
ZgRNS Git Node

Node / mirrors / micropython-reticulum / files / firmware / example_sensor.py

Displaying Raw • Download

firmware/example_sensor.py rns-152-frame-hardening (97447676) Text, 9.66 KB

T8b949e"""
µReticulum Example: LXMF Sensor Client with Deepsleep
========================================
Compatible with MeshChat, Sideband, NomadNet over UDP on the same LAN.

Usage (MicroPython on ESP32-S3 / RP2040):
1. Edit config.py — set WiFi credentials, node name, interfaces and sensor 'hub' (LXMF address for data to be sent to)
2. Copy the urns/ folder, config.py, and this file to the device
3. Uncomment peripherals you have connected below
4. Copy example.sensor.py to main.py
4. Run with: import main

Process
1. Device boots from sleep
2. Connects to network (e.g. WiFi)
3. Announces
4. Collects data from sensors
5. Sends data string with send_data()
6. Waits preset amount of time
7. Shuts down µReticulum
8. Goes into deepsleep with a timer to wake

"""

Tff7b72from T7ee787config Tff7b72import Te6edf3WIFI_SSIDTb4b4b4, Te6edf3WIFI_PASSTb4b4b4, Te6edf3NODE_NAMETb4b4b4, Te6edf3DEBUGTb4b4b4, Te6edf3CONFIGTb4b4b4, Te6edf3SENSOR_HUB

Tff7b72import T7ee787machineTff7b72, T7ee787time
Tff7b72import T7ee787gc
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

T8b949e# ---- Peripherals ----
T8b949e# Uncomment the ones you have connected. Shared I2C bus for I2C devices.
T8b949e#from machine import Pin, SoftI2C
T8b949e#i2c = SoftI2C(scl=Pin(6), sda=Pin(5), freq=100000)

T8b949e#import peripherals.bme280_sensor as bme_sensor
T8b949e#bme_sensor.init(i2c)

T8b949e# import peripherals.neopixel_led as neopixel_led
T8b949e# neopixel_led.init(pin=21)

T8b949e#import peripherals.gpio_control as gpio
T8b949e#gpio.init({"lamp": (21, "OUT")})

Tff7b72import T7ee787peripheralsT7ee787.T7ee787adc_reader Tff7b72as T7ee787adc_reader
Te6edf3adc_readerTff7b72.Td2a8ffinitTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffbatteryTa5d6ff"Tb4b4b4: T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffmoistureTa5d6ff"Tb4b4b4: T79c0ff10Tb4b4b4}Tb4b4b4)

T8b949e# import peripherals.sds011_sensor as sds011_sensor
T8b949e# sds011_sensor.init(uart_id=1, tx_pin=43, rx_pin=44)

T8b949e# List all active peripherals here (must match uncommented imports above)
Te6edf3active_peripherals Tff7b72= Tb4b4b4[Te6edf3adc_readerTb4b4b4]

Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

T8b949e# ---- Echo reply ----
Te6edf3ECHO_REPLY Tff7b72= Tff7b72True


Tff7b72async Tff7b72def Td2a8ffsend_dataTb4b4b4(Te6edf3routerTb4b4b4, Te6edf3sensor_hub_addrTb4b4b4, Te6edf3contentTb4b4b4)Tb4b4b4:
T8b949e"""Send data as async task (crypto takes ~7s, must not block poll loop)."""
Tff7b72import T7ee787uasyncio Tff7b72as T7ee787asyncio

T8b949e# Yield so the poll loop can resume immediately
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0Tb4b4b4)

Te6edf3sensor_hub_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3sensor_hub_addrTb4b4b4)

Tff7b72tryTb4b4b4:

Te6edf3msg Tff7b72= Te6edf3routerTff7b72.Td2a8ffsend_messageTb4b4b4(Te6edf3sensor_hub_hashTb4b4b4, Te6edf3contentTb4b4b4)
Tff7b72if Te6edf3msgTb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff[SENSOR] Sent to Ta5d6ff" Tff7b72+ Te6edf3sensor_hub_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff[SENSOR] Cannot send to Ta5d6ff" Tff7b72+ Te6edf3sensor_hub_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4] Tff7b72+ Ta5d6ff"Ta5d6ff (unknown identity)Ta5d6ff"Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72from T7ee787urnsT7ee787.T7ee787log Tff7b72import Te6edf3logTb4b4b4, Te6edf3LOG_ERROR
Te6edf3logTb4b4b4(Ta5d6ff"Ta5d6ff[Err] error: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3LOG_ERRORTb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

Tff7b72async Tff7b72def Td2a8ffsend_echo_replyTb4b4b4(Te6edf3routerTb4b4b4, Te6edf3source_hashTb4b4b4, Te6edf3contentTb4b4b4)Tb4b4b4:
T8b949e"""Send echo reply as async task (crypto takes ~7s, must not block poll loop)."""
Tff7b72import T7ee787uasyncio Tff7b72as T7ee787asyncio

T8b949e# Yield so the poll loop can resume immediately
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0Tb4b4b4)

Tff7b72tryTb4b4b4:
Te6edf3reply_content Tff7b72= Ta5d6ff"Ta5d6ffEcho: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3contentTb4b4b4)
Te6edf3msg Tff7b72= Te6edf3routerTff7b72.Td2a8ffsend_messageTb4b4b4(Te6edf3source_hashTb4b4b4, Te6edf3reply_contentTb4b4b4)
Tff7b72if Te6edf3msgTb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff[Echo] Replied to Ta5d6ff" Tff7b72+ Te6edf3source_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff[Echo] Cannot reply to Ta5d6ff" Tff7b72+ Te6edf3source_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4] Tff7b72+ Ta5d6ff"Ta5d6ff (unknown identity)Ta5d6ff"Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72from T7ee787urnsT7ee787.T7ee787log Tff7b72import Te6edf3logTb4b4b4, Te6edf3LOG_ERROR
Te6edf3logTb4b4b4(Ta5d6ff"Ta5d6ffEcho reply error: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3LOG_ERRORTb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffconnect_wifiTb4b4b4(Te6edf3ssidTb4b4b4, Te6edf3passwordTb4b4b4, Te6edf3timeoutTff7b72=T79c0ff15Tb4b4b4)Tb4b4b4:
Tff7b72import T7ee787sys
Tff7b72import T7ee787network
Tff7b72import T7ee787time

Te6edf3platform Tff7b72= Te6edf3sysTff7b72.Td2a8ffplatform T8b949e# "esp32" or "rp2"

T8b949e# ESP32-S3: deactivate AP interface — dual-interface mode routes broadcast
T8b949e# packets to AP instead of STA, preventing UDP broadcast reception.
Tff7b72if Te6edf3platform Tff7b72== Ta5d6ff"Ta5d6ffesp32Ta5d6ff"Tb4b4b4:
Te6edf3ap Tff7b72= Te6edf3networkTff7b72.Td2a8ffWLANTb4b4b4(Te6edf3networkTff7b72.Td2a8ffAP_IFTb4b4b4)
Tff7b72if Te6edf3apTff7b72.Td2a8ffactiveTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3apTff7b72.Td2a8ffactiveTb4b4b4(Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff2Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffAP_IF deactivatedTa5d6ff"Tb4b4b4)

Te6edf3wlan Tff7b72= Te6edf3networkTff7b72.Td2a8ffWLANTb4b4b4(Te6edf3networkTff7b72.Td2a8ffSTA_IFTb4b4b4)
Te6edf3wlanTff7b72.Td2a8ffactiveTb4b4b4(Tff7b72TrueTb4b4b4)
Tff7b72if Tff7b72not Te6edf3wlanTff7b72.Td2a8ffisconnectedTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffConnecting to WiFi:Ta5d6ff"Tb4b4b4, Te6edf3ssidTb4b4b4)
Te6edf3wlanTff7b72.Td2a8ffconnectTb4b4b4(Te6edf3ssidTb4b4b4, Te6edf3passwordTb4b4b4)
Te6edf3start Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72while Tff7b72not Te6edf3wlanTff7b72.Td2a8ffisconnectedTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3start Tff7b72> Te6edf3timeoutTb4b4b4:
Tff7b72raise Tf85149RuntimeErrorTb4b4b4(Ta5d6ff"Ta5d6ffWiFi connection timed outTa5d6ff"Tb4b4b4)
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.5Tb4b4b4)

T8b949e# Disable WiFi power management to reliably receive broadcast UDP
Tff7b72if Te6edf3platform Tff7b72== Ta5d6ff"Ta5d6ffesp32Ta5d6ff"Tb4b4b4:
Te6edf3wlanTff7b72.Td2a8ffconfigTb4b4b4(Te6edf3pmTff7b72=T79c0ff0Tb4b4b4)
Tff7b72elif Te6edf3platform Tff7b72== Ta5d6ff"Ta5d6ffrp2Ta5d6ff"Tb4b4b4:
Te6edf3wlanTff7b72.Td2a8ffconfigTb4b4b4(Te6edf3pmTff7b72=T79c0ff0xa11140Tb4b4b4)

Te6edf3ip Tff7b72= Te6edf3wlanTff7b72.Td2a8ffifconfigTb4b4b4(Tb4b4b4)Tb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffConnected! IP:Ta5d6ff"Tb4b4b4, Te6edf3ipTb4b4b4, Ta5d6ff"Ta5d6ff(Ta5d6ff" Tff7b72+ Te6edf3platform Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72import T7ee787ntptime
Te6edf3ntptimeTff7b72.Td2a8ffsettimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffNTP syncedTa5d6ff"Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffNTP sync failed:Ta5d6ff"Tb4b4b4, Te6edf3eTb4b4b4)

Tff7b72return Te6edf3ip


Tff7b72def Td2a8ffsetup_nodeTb4b4b4(Te6edf3rnsTb4b4b4, Te6edf3node_nameTb4b4b4)Tb4b4b4:
Tff7b72from T7ee787urnsT7ee787.T7ee787lxmf Tff7b72import Te6edf3LXMRouter
Te6edf3router Tff7b72= Te6edf3LXMRouterTb4b4b4(Te6edf3identityTff7b72=Te6edf3rnsTff7b72.Td2a8ffidentityTb4b4b4)
Te6edf3dest Tff7b72= Te6edf3routerTff7b72.Td2a8ffregister_delivery_identityTb4b4b4(Te6edf3rnsTff7b72.Td2a8ffidentityTb4b4b4, Te6edf3display_nameTff7b72=Te6edf3node_nameTb4b4b4)

T8b949e# Incoming LXMF message handler (proof is sent automatically by LXMRouter)
Tff7b72def Td2a8ffon_messageTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4:
Tff7b72import T7ee787uasyncio Tff7b72as T7ee787asyncio

Te6edf3verified Tff7b72= Ta5d6ff"Ta5d6ffverifiedTa5d6ff" Tff7b72if Te6edf3messageTff7b72.Td2a8ffsignature_validated Tff7b72else Ta5d6ff"Ta5d6ffUNVERIFIEDTa5d6ff"
Te6edf3sender Tff7b72= Te6edf3messageTff7b72.Td2a8ffsource_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]
Te6edf3content Tff7b72= Te6edf3messageTff7b72.Td2a8ffcontent_as_stringTb4b4b4(Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff(binary)Ta5d6ff"

T8b949e# Run content through active peripherals
Te6edf3results Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3p Tff7b72in Te6edf3active_peripheralsTb4b4b4:
Te6edf3result Tff7b72= Te6edf3pTff7b72.Td2a8ffprocessTb4b4b4(Te6edf3contentTb4b4b4)
Tff7b72if Te6edf3resultTb4b4b4:
Te6edf3resultsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3resultTb4b4b4)
Tff7b72if Te6edf3resultsTb4b4b4:
Te6edf3content Tff7b72= Ta5d6ff"Tffea00\nTa5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3resultsTb4b4b4)

Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff=Ta5d6ff" Tff7b72* T79c0ff40Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffLXMF Message [Ta5d6ff" Tff7b72+ Te6edf3verified Tff7b72+ Ta5d6ff"Ta5d6ff]Ta5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff From: Ta5d6ff" Tff7b72+ Te6edf3senderTb4b4b4)
Te6edf3title Tff7b72= Te6edf3messageTff7b72.Td2a8fftitle_as_stringTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3titleTb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff Title: Ta5d6ff" Tff7b72+ Te6edf3titleTb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff Content: Ta5d6ff" Tff7b72+ Te6edf3contentTb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff=Ta5d6ff" Tff7b72* T79c0ff40Tb4b4b4)

T8b949e# Queue async echo reply (non-blocking)
Tff7b72if Te6edf3ECHO_REPLYTb4b4b4:
Te6edf3asyncioTff7b72.Td2a8ffcreate_taskTb4b4b4(Te6edf3send_echo_replyTb4b4b4(Te6edf3routerTb4b4b4, Te6edf3messageTff7b72.Td2a8ffsource_hashTb4b4b4, Te6edf3contentTb4b4b4)Tb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

Te6edf3routerTff7b72.Td2a8ffregister_delivery_callbackTb4b4b4(Te6edf3on_messageTb4b4b4)

T8b949e# Announce handler — see other LXMF peers
Tff7b72def Td2a8ffon_announceTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3display_nameTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff[Peer] Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3display_name Tff7b72or Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff [Ta5d6ff" Tff7b72+ Te6edf3destination_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4] Tff7b72+ Ta5d6ff"Ta5d6ff]Ta5d6ff"Tb4b4b4)

Te6edf3routerTff7b72.Td2a8ffregister_announce_callbackTb4b4b4(Te6edf3on_announceTb4b4b4)

Tff7b72return Te6edf3destTb4b4b4, Te6edf3router


Tff7b72def Td2a8ffneeds_wifiTb4b4b4(Te6edf3configTb4b4b4)Tb4b4b4:
T8b949e"""Check if any UDP or TCP interface is enabled in config."""
Tff7b72for Te6edf3iface Tff7b72in Te6edf3configTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3ifaceTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffenabledTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4) Tff7b72and Te6edf3ifaceTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4) Tff7b72in Tb4b4b4(
Ta5d6ff"Ta5d6ffUDPInterfaceTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffTCPClientInterfaceTa5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72return Tff7b72False


Tff7b72def Td2a8ffmainTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Run on MicroPython (ESP32-S3, RP2040, etc.)"""
Tff7b72import T7ee787uasyncio Tff7b72as T7ee787asyncio

Tff7b72if Te6edf3needs_wifiTb4b4b4(Te6edf3CONFIGTb4b4b4)Tb4b4b4:
Te6edf3ip Tff7b72= Te6edf3connect_wifiTb4b4b4(Te6edf3WIFI_SSIDTb4b4b4, Te6edf3WIFI_PASSTb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

Tff7b72from T7ee787urns Tff7b72import Te6edf3Reticulum
Tff7b72from T7ee787urnsT7ee787.T7ee787log Tff7b72import Te6edf3LOG_NONETb4b4b4, Te6edf3LOG_NOTICETb4b4b4, Te6edf3LOG_DEBUG

Te6edf3log_map Tff7b72= Tb4b4b4{T79c0ff0Tb4b4b4: Te6edf3LOG_NONETb4b4b4, T79c0ff1Tb4b4b4: Te6edf3LOG_NONETb4b4b4, T79c0ff2Tb4b4b4: Te6edf3LOG_DEBUGTb4b4b4}
Te6edf3rns Tff7b72= Te6edf3ReticulumTb4b4b4(Te6edf3loglevelTff7b72=Te6edf3log_mapTff7b72.Td2a8ffgetTb4b4b4(Te6edf3DEBUGTb4b4b4, Te6edf3LOG_NOTICETb4b4b4)Tb4b4b4)
Te6edf3rnsTff7b72.Td2a8ffconfig Tff7b72= Te6edf3CONFIG

Te6edf3new_node_name Tff7b72= Ta5d6ff"Tffd700{}Ta5d6ff"Tff7b72.Td2a8ffformatTb4b4b4(Te6edf3NODE_NAMETb4b4b4)

Te6edf3destTb4b4b4, Te6edf3router Tff7b72= Te6edf3setup_nodeTb4b4b4(Te6edf3rnsTb4b4b4, Te6edf3new_node_nameTb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

Te6edf3rnsTff7b72.Td2a8ffsetup_interfacesTb4b4b4(Tb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

T8b949e# Calling machine.RTC() should set system time from RTC
T8b949e# RTC can be set with mpremote rtc --set
Te6edf3rtc Tff7b72= Te6edf3machineTff7b72.Td2a8ffRTCTb4b4b4(Tb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffLXMF address:Ta5d6ff"Tb4b4b4, Te6edf3destTff7b72.Td2a8ffhexhashTb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffFree memory:Ta5d6ff"Tb4b4b4, Te6edf3gcTff7b72.Td2a8ffmem_freeTb4b4b4(Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffbytesTa5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffRTC Time:Ta5d6ff"Tb4b4b4, Te6edf3rtcTff7b72.Td2a8ffdatetimeTb4b4b4(Tb4b4b4)Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffRunning... (Ctrl+C to stop)Ta5d6ff"Tb4b4b4)

T8b949e# Deferred initial announce — runs AFTER poll loop starts
Tff7b72async Tff7b72def Td2a8ffinitial_announceTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.5Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3routerTff7b72.Td2a8ffannounceTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffAnnounced as:Ta5d6ff"Tb4b4b4, Te6edf3new_node_nameTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff2Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffInitial announce error:Ta5d6ff"Tb4b4b4, Te6edf3eTb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

T8b949e# Add periodic re-announce to the event loop
Tff7b72async Tff7b72def Td2a8ffreannounce_loopTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72TrueTb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff120Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3routerTff7b72.Td2a8ffannounceTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff2Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff[Re-announced]Ta5d6ff"Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff2Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffRe-announce error:Ta5d6ff"Tb4b4b4, Te6edf3eTb4b4b4)
Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Tb4b4b4)

T8b949e# Go into deep sleep
Tff7b72async Tff7b72def Td2a8ffstart_deepsleepTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72import T7ee787machine

Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff2Tb4b4b4)

Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffPreparing for deepsleepTa5d6ff"Tb4b4b4)
Te6edf3rnsTff7b72.Td2a8ffshutdownTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffShutdown completeTa5d6ff"Tb4b4b4)

Te6edf3machineTff7b72.Td2a8ffdeepsleepTb4b4b4(T79c0ff60000Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffDeepsleep - should not printTa5d6ff"Tb4b4b4)

T8b949e# Send Data
Tff7b72async Tff7b72def Td2a8ffsend_sensor_dataTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff5Tb4b4b4)
Te6edf3moisture_sensor_raw Tff7b72= Te6edf3adc_readerTff7b72.Td2a8ffprocessTb4b4b4(Ta5d6ff"Ta5d6ffmoistureTa5d6ff"Tb4b4b4)
Te6edf3battery_sensor_raw Tff7b72= Te6edf3adc_readerTff7b72.Td2a8ffprocessTb4b4b4(Ta5d6ff"Ta5d6ffbatteryTa5d6ff"Tb4b4b4)

Te6edf3reply_content Tff7b72= Ta5d6ff"Ta5d6ffA1: Tffd700{}Ta5d6ff,Tffd700{}Ta5d6ff"Tff7b72.Td2a8ffformatTb4b4b4(Te6edf3battery_sensor_rawTb4b4b4, Te6edf3moisture_sensor_rawTb4b4b4)

Te6edf3asyncioTff7b72.Td2a8ffcreate_taskTb4b4b4(Te6edf3send_dataTb4b4b4(Te6edf3routerTb4b4b4, Te6edf3SENSOR_HUBTb4b4b4, Te6edf3reply_contentTb4b4b4)Tb4b4b4)
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff10Tb4b4b4)
Tff7b72await Te6edf3start_deepsleepTb4b4b4(Tb4b4b4)

T8b949e# Patch rns.run to include our announce + reannounce tasks
Te6edf3_original_run Tff7b72= Te6edf3rnsTff7b72.Td2a8ffrun

Tff7b72async Tff7b72def Td2a8ffrun_with_reannounceTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3asyncioTff7b72.Td2a8ffcreate_taskTb4b4b4(Te6edf3initial_announceTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3asyncioTff7b72.Td2a8ffcreate_taskTb4b4b4(Te6edf3reannounce_loopTb4b4b4(Tb4b4b4)Tb4b4b4)
T8b949e# Start SDS011 periodic measurement if active
T8b949e# if sds011_sensor.sensor: sds011_sensor.start()
Te6edf3asyncioTff7b72.Td2a8ffcreate_taskTb4b4b4(Te6edf3send_sensor_dataTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72await Te6edf3_original_runTb4b4b4(Tb4b4b4)

Tff7b72tryTb4b4b4:
Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4(Te6edf3run_with_reannounceTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149KeyboardInterruptTb4b4b4:
Te6edf3rnsTff7b72.Td2a8ffshutdownTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3DEBUG Tff7b72>Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffShutdown completeTa5d6ff"Tb4b4b4)


Te6edf3mainTb4b4b4(Tb4b4b4)

Served by rngit 1.5.2 - Generated in 0.06s